package com.deep.bilibili.config;


import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

@ControllerAdvice
public class MyGlobalHandler {

    @ModelAttribute
    public void title(Model model) {
        //
        model.addAttribute("activeLink", "Bibili后台管理系统");
        model.addAttribute("title", "Bibili后台管理系统");
        model.addAttribute("short_title", "后台管理系统");

        String adminerName = "anonymousUser";
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (Optional.ofNullable(auth).isPresent()) {
            //
            Object principal = auth.getPrincipal();
            if (principal instanceof String) {
//                model.addAttribute("adminerName", "anonymousUser");
                adminerName = "anonymousUser";
            }
            if (principal instanceof org.springframework.security.core.userdetails.User) {
                User adminer = (User) auth.getPrincipal();
//            String adminerName = principal.getName();
                adminerName = adminer.getUsername();
                model.addAttribute("adminerName", adminerName);
            }
        }

        model.addAttribute("adminerName", adminerName);
    }

    @ModelAttribute
    public void presetParam(Model model) {
        model.addAttribute("globalAttr", "this is a global attribute");
    }

    @ModelAttribute()
    public Map<String, String> presetParam() {
        Map<String, String> map = new HashMap<>();
        map.put("key1", "value1");
        map.put("key2", "value2");
        map.put("key3", "value3");
        return map;
    }


    @InitBinder
    public void processParam(WebDataBinder dataBinder) {

        /*
         * 创建一个字符串微调编辑器
         * 参数{boolean emptyAsNull}: 是否把空字符串("")视为 null
         */
        StringTrimmerEditor trimmerEditor = new StringTrimmerEditor(true);

        /*
         * 注册自定义编辑器
         * 接受两个参数{Class<?> requiredType, PropertyEditor propertyEditor}
         * requiredType：所需处理的类型
         * propertyEditor：属性编辑器，StringTrimmerEditor就是 propertyEditor的一个子类
         */
        dataBinder.registerCustomEditor(String.class, trimmerEditor);

        //同上，这里就不再一步一步讲解了
        dataBinder.registerCustomEditor(Date.class,
                new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), false));
    }


    /*
     * @InitBinder("person") 对应找到@RequstMapping标识的方法参数中
     * 找参数名为person的参数。
     * 在进行参数绑定的时候，以‘p.’开头的都绑定到名为person的参数中。
     */
    @InitBinder("person")
    public void BindPerson(WebDataBinder dataBinder) {
        dataBinder.setFieldDefaultPrefix("p.");
    }

    @InitBinder("book")
    public void BindBook(WebDataBinder dataBinder) {
        dataBinder.setFieldDefaultPrefix("b.");
    }

    private HttpServletRequest currentRequest() {
        // Use getRequestAttributes because of its return null if none bound
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return Optional.ofNullable(servletRequestAttributes).map(ServletRequestAttributes::getRequest).orElse(null);
    }

}
